package com.yhm.NIO.NIOSelector;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class YhmNIOServer {


  public static void main(String[] args) {
    try {
      ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();//创建实例
      Selector selector = Selector.open();//创建实例
      serverSocketChannel.configureBlocking(false);
      SelectionKey selectionKey = serverSocketChannel.register(selector, 0, serverSocketChannel);
      selectionKey.interestOps(SelectionKey.OP_ACCEPT);//对客户端连接 事件 感兴趣
      serverSocketChannel.bind(new InetSocketAddress(8080));//
      System.out.println("服务端绑定端口成功");

      while (selector.select()!=0) {//select方法是阻塞的

        Set selectionKeySet = selector.selectedKeys();//获取到所有的事件
        Iterator<SelectionKey> iterable = selectionKeySet.iterator();
        while (iterable.hasNext()) {
          SelectionKey key = iterable.next();
          iterable.remove();//移除当前事件
          if (key.isAcceptable()) {
            ServerSocketChannel serverSocketChannel1 = (ServerSocketChannel) key.attachment();
            serverSocketChannel1.configureBlocking(false);//配置非阻塞
            SocketChannel serverSocket = serverSocketChannel1.accept();
            serverSocket.configureBlocking(false);
            SelectionKey selectionKey1 = serverSocket.register(selector, 0, serverSocket);//注册selector
            selectionKey1.interestOps(SelectionKey.OP_READ);//只对可读事件感兴趣

          } else if (key.isReadable()) {
            SocketChannel socketChannel = (SocketChannel) key.attachment();
            try {
              ByteBuffer readBuffer = ByteBuffer.allocate(1024);
              while (socketChannel.isOpen() && (socketChannel.read(readBuffer) != -1)) {
                if (readBuffer.position() > 0) break;
              }

              //接收数据
              readBuffer.flip();
              byte[] receiveBytes = new byte[readBuffer.limit()];
              readBuffer.get(receiveBytes);
              System.out.println("接收到客户端数据" + new String(receiveBytes));

              //发送数据
              ByteBuffer sendBuffer = ByteBuffer.wrap(("服务端返回" + Math.random() + "数据").getBytes());
              while (socketChannel.isOpen() && (socketChannel.write(sendBuffer) != -1)) {
                if (sendBuffer.position() > 0) {
                  break;
                }
              }
              socketChannel.close();
            } catch (Exception e) {

            }
          }

        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
